feat(traits): add ControlDependence family + refactor strict-contract helpers - #471
Merged
Conversation
- New strict opt-in family with tags ControlFree and WithControl for encoding control presence in OCPs at the type level, ready for dispatch in downstream packages - Factor shared contract helpers _throw_missing_trait and _throw_trait_not_implemented to eliminate 70% duplication across time_dependence, variable_dependence, and mutability families; behaviour and messages unchanged - Generalise _caller_function_name stacktrace filter to match any has_<family>_trait predicate (startswith + endswith pattern) instead of hard-coded names - Collapse has_variable duplicate to direct alias is_variable(obj) - Add 25 unit tests mirroring variable_dependence test structure; Traits suite: 301/301 ✓ - Document the two trait templates (strict opt-in vs default-valued capability) in module docstring; add control-dependence section to guide/traits.md with rationale for abstract-vs-concrete trait types (abstract used for type-param-only axes) - Update api_reference.jl to include control_dependence.jl in the auto-generated API page Follows the exact pattern of variable_dependence for consistency. No changes to existing predicates; _caller_function_name detection now names is_control_free through the new shared helper chain. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new trait family
ControlDependenceto CTBase.Traits and refactors the internal trait-contract machinery to eliminate duplication.What changed
New ControlDependence family — a strict opt-in trait encoding whether an optimal control problem carries a control input:
ControlFree(no control: ẋ = f(t,x,v)) andWithControl(with control: ẋ = f(t,x,u,v))has_control_dependence_traitandcontrol_dependenceaccessorsis_control_freeandhas_controlFlow(ocp)dispatchRefactored strict-contract helpers — eliminated 70% duplication across time_dependence, variable_dependence, mutability, and now control_dependence:
_throw_missing_traitand_throw_trait_not_implementedfactor the fallback exception bodies_caller_function_namestacktrace filter: now matches anyhas_<family>_traitname via pattern matching instead of a hard-coded blacklistMinor cleanups:
has_variableduplicate to direct alias:has_variable(obj) = is_variable(obj)control_dependence.jlto the auto-generated API page indocs/api_reference.jlDocumentation:
guide/traits.mdwith examplesWhy this matters
Control-dependence will unblock PR2 (CTModels) and PR3 (CTFlows) in the ecosystem-wide traits cleanup:
Model, reading from the type ofocp.control(EmptyControlModel → ControlFree), makingis_control_freetype-stable instead of runtime.Flow(ocp)on the trait, properly routing to different code paths and closing a latent correctness bug where a with-control OCP would silently mis-build a Hamiltonian.Verification
is_control_free(3.14)names the predicate correctly through the new shared-helper chainDesign philosophy
The ControlDependence family follows the exact pattern of VariableDependence — a verbatim calque with proven precedent. No macro abstraction yet; the shared helper refactor is sufficient at 4 families. If a 5th strict family appears, that's the trigger to extract a
@trait_contractmacro to eliminate remaining boilerplate.🤖 Generated with Claude Code